package com.example.myapplication.function.musicmode

import android.util.Log

/**
 * 3. 基于FFT的频域降噪（高级）
 */
class SpectralNoiseReducer {
    companion object {
        private const val FFT_SIZE = 1024
        private const val SAMPLE_RATE = 44100
    }
    
    private val fft = FFT(FFT_SIZE)
    private val noiseProfile = FloatArray(FFT_SIZE / 2)
    private var isNoiseProfileSet = false
    
    /**
     * 使用FFT进行频域降噪
     */
    fun spectralReduceNoise(audioData: FloatArray): FloatArray {
        if (audioData.size != FFT_SIZE) {
            Log.w("com.example.myapplication.function.musicmode.SpectralNoiseReducer", "Input size must be $FFT_SIZE")
            return audioData
        }
        
        // 应用窗函数
        val windowedData = applyHammingWindow(audioData)
        
        // 执行FFT
        val fftResult = performFFT(windowedData)
        
        // 频谱降噪
        val denoisedSpectrum = applySpectralNoiseReduction(fftResult)
        
        // 执行逆FFT
        val denoisedData = performInverseFFT(denoisedSpectrum)
        
        return denoisedData
    }
    
    /**
     * 学习噪音样本，建立噪音频谱模板
     */
    fun learnNoiseProfile(noiseSamples: List<FloatArray>) {
        if (noiseSamples.isEmpty()) return
        
        val profile = FloatArray(FFT_SIZE / 2)
        
        noiseSamples.forEach { sample ->
            val windowed = applyHammingWindow(sample)
            val spectrum = performFFT(windowed)
            
            for (i in profile.indices) {
                profile[i] += spectrum[i]
            }
        }
        
        // 平均化
        for (i in profile.indices) {
            noiseProfile[i] = profile[i] / noiseSamples.size
        }
        
        isNoiseProfileSet = true
        Log.d("com.example.myapplication.function.musicmode.SpectralNoiseReducer", "Noise profile learned")
    }
    
    private fun applyHammingWindow(data: FloatArray): FloatArray {
        val windowed = FloatArray(FFT_SIZE)
        for (i in data.indices) {
            val hamming = 0.54 - 0.46 * Math.cos(2 * Math.PI * i / (FFT_SIZE - 1))
            windowed[i] = (data[i] * hamming).toFloat()
        }
        return windowed
    }
    
    private fun performFFT(data: FloatArray): FloatArray {
        // 这里需要实现FFT算法
        // 简化实现，返回幅度谱
        val spectrum = FloatArray(FFT_SIZE / 2)
        
        // 实际应用中应该使用专业的FFT库
        // 这里使用简化的频域分析
        for (i in spectrum.indices) {
            spectrum[i] = Math.sqrt((data[i] * data[i]).toDouble()).toFloat()
        }
        
        return spectrum
    }
    
    private fun applySpectralNoiseReduction(spectrum: FloatArray): FloatArray {
        if (!isNoiseProfileSet) return spectrum
        
        val denoised = FloatArray(spectrum.size)
        
        for (i in spectrum.indices) {
            // 谱减法：从信号频谱中减去噪音频谱
            val denoisedValue = spectrum[i] - noiseProfile[i]
            denoised[i] = Math.max(denoisedValue, 0.01f).toFloat() // 避免负值
        }
        
        return denoised
    }
    
    private fun performInverseFFT(spectrum: FloatArray): FloatArray {
        // 执行逆FFT，将频域转换回时域
        // 简化实现
        val timeData = FloatArray(FFT_SIZE)
        
        // 实际应用中应该使用专业的FFT库
        // 这里返回原始数据的简化版本
        for (i in timeData.indices) {
            timeData[i] = spectrum[i % spectrum.size] * 0.1f // 简化处理
        }
        
        return timeData
    }
}

// 简化的FFT类（实际项目中建议使用现成的FFT库）
class FFT(private val size: Int) {
    fun forward(input: FloatArray): FloatArray {
        // FFT实现
        return FloatArray(size)
    }
    
    fun inverse(input: FloatArray): FloatArray {
        // 逆FFT实现
        return FloatArray(size)
    }
}